﻿package com.ascainiao3d.display
{
	import flash.display.Graphics;
	public class Triangle
	{
		private var pointA:Point3D;
		private var pointB:Point3D;
		private var pointC:Point3D;
		private var color:uint;
		public var light:Light;
		public var is_mask:Boolean=false;//是否被遮挡
		public function Triangle(a:Point3D,b:Point3D,c:Point3D,color:uint)
		{
			pointA = a;
			pointB = b;
			pointC = c;
			this.color = color;
		}
		public function draw(g:Graphics):void
		{
			if (isBackFace()||is_mask)
			{
				return;
			}
			g.lineStyle(0.5,0x000000);
			g.beginFill(getAdjustedColor());
			g.moveTo(pointA.screenX,pointA.screenY);
			g.lineTo(pointB.screenX,pointB.screenY);
			g.lineTo(pointC.screenX,pointC.screenY);
			g.lineStyle(0.5,0x000000,0);
			g.lineTo(pointA.screenX,pointA.screenY);
			g.endFill();
		}
		private function getAdjustedColor():uint
		{
			var red:Number = color >> 16;
			var green:Number = color >> 8 & 0xff;
			var blue:Number = color & 0xff;
			var lightFactor:Number = getLightFactor();
			red *=  lightFactor;
			green *=  lightFactor;
			blue *=  lightFactor;
			return red << 16 | green << 8 | blue;
		}
		private function getLightFactor():Number
		{
			var ab:Object = new Object  ;
			ab.x = pointA.x - pointB.x;
			ab.y = pointA.y - pointB.y;
			ab.z = pointA.z - pointB.z;
			var bc:Object = new Object  ;
			bc.x = pointB.x - pointC.x;
			bc.y = pointB.y - pointC.y;
			bc.z = pointB.z - pointC.z;
			var norm:Object = new Object  ;
			norm.x = ab.y * bc.z - ab.z * bc.y;
			norm.y =  -(ab.x * bc.z - ab.z * bc.x);
			norm.z = ab.x * bc.y - ab.y * bc.x;
			var dotProd:Number = norm.x * light.x + norm.y * light.y + norm.z * light.z;
			var normMag:Number = Math.sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);
			var lightMag:Number = Math.sqrt(light.x * light.x + light.y * light.y + light.z * light.z);
			//trace((dotProd / normMag) * lightMag);
			return Math.acos((dotProd /( normMag * lightMag))) / Math.PI * light.brightness;
		}
		private function isBackFace():Boolean
		{
			// 见 http://www.jurjans.lv/flash/shape.html
			var cax:Number = pointC.screenX - pointA.screenX;
			var cay:Number = pointC.screenY - pointA.screenY;
			var bcx:Number = pointB.screenX - pointC.screenX;
			var bcy:Number = pointB.screenY - pointC.screenY;
			return cax * bcy > cay * bcx;
		}
		public function get depth():Number
		{
			var zpos:Number = Math.min(pointA.z,pointB.z);
			zpos = Math.min(zpos,pointC.z);
			return zpos;
		}
	}
}